package com.yeswater.redis7.service;

import com.yeswater.redis7.Constant;
import com.yeswater.redis7.entity.Customer;
import com.yeswater.redis7.filter.GuavaBloomFilter;
import com.yeswater.redis7.filter.MyBloomFilter;
import com.yeswater.redis7.mapper.CustomerMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @author： yeswater
 * @create： 2024/6/28
 */

@Service
@Slf4j
public class CustomerService {
	
	@Resource
	private CustomerMapper customerMapper;
	@Resource
	private RedisTemplate redisTemplate;
	@Resource
	private MyBloomFilter bloomFilter;
	
	@Resource
	private GuavaBloomFilter guavaBloomFilter;
	
	public void addCustomer(Customer customer) {
		int i = customerMapper.insertSelective(customer);
		
		if (i > 0) {
			System.out.println(customer.getId());
			//到数据库里面，重新捞出新数据出来，做缓存
			customer = customerMapper.selectByPrimaryKey(customer.getId());
			//缓存key
			String uid = Constant.CACHE_KEY_CUSTOMER + customer.getId();
			//往mysql里面插入成功随后再从mysql查询出来，再插入redis
			redisTemplate.opsForValue().set(uid, customer);
			bloomFilter.addWhitelistCustomer(uid);
			guavaBloomFilter.addWhitelistCustomer(uid);
		}
	}
	
	public Customer findCustomerById(Integer customerId) {
		Customer customer = null;
		//缓存key的名称
		String key = Constant.CACHE_KEY_CUSTOMER + customerId;
		//1 查询redis
		customer = (Customer) redisTemplate.opsForValue().get(key);
		//redis无，进一步查询mysql
		if (customer == null) {
			synchronized (CustomerService.class) {
				//2 从mysql查出来customer
				customer = customerMapper.selectByPrimaryKey(customerId);
				// mysql有，redis无
				if (customer != null) {
					//3 把mysql捞到的数据写入redis，方便下次查询能redis命中。
					redisTemplate.opsForValue().set(key, customer,24*60*60, TimeUnit.SECONDS);
				}
			}
		}
		return customer;
	}
	
	public Customer findCustomerByIdWithBloomFilter(Integer customerId) {
		Customer customer = null;
		String key = Constant.CACHE_KEY_CUSTOMER + customerId;
		
		// 布隆过滤器白名单校验，无是绝对无，有是可能有
		if (!bloomFilter.checkWhitelistCustomer(key)) {
			log.info("白名单无此顾客:{} ,不可访问",key);
			return null;
		}
		
		// guava 布隆过滤器
		if (!guavaBloomFilter.checkWhitelistCustomer(key)) {
			log.info("白名单无此顾客:{} ,不可访问",key);
			return null;
		}
		
		customer = (Customer) redisTemplate.opsForValue().get(key);
		if (customer == null) {
			synchronized (CustomerService.class) {
				customer = customerMapper.selectByPrimaryKey(customerId);
				if (customer != null) {
					redisTemplate.opsForValue().set(key, customer);
				}
			}
		}
		return customer;
	}
	
}
